# __init__ 的使用
# __init__ 可以理解为是一种特殊的方法（魔法方法），当执行创建对象的语句时，它会被自动调用，
# 再结合对象属性一般在类内定义，则可知对象属性的定义方法一般就是魔法方法 __init__


class Cat:
    def __init__(self, name, age):
        """这就是属性定义函数（方法），self 仍旧是自动传参（对象），对象想要几个属性就多放几个形参"""
        self.name = name
        self.age = age

    def show_info(self):
        """这是随意定义的一种方法，用来结束测试"""
        print(f'这只小猫的名字是{self.name},它的年龄是{self.age}。')

    def __str__(self):
        """这是一种作为打印对象输出结果（想要执行打印对象后输出什么就定义什么即可）的方法，输出必须有一个字符串返回"""
        return f'这只小猫的名字是{self.name},它的年龄是{self.age}。'  # 显然这个方法可以替代 show_info 方法


blue_cat = Cat('小蓝', 3)  # 在创建对象的同时，把自身的属性值传参
red_cat = Cat('小红', 2)
blue_cat.show_info()
red_cat.show_info()
b = blue_cat  # 要注意这里不是创建对象，实际是将blue_cat该对象的引用又引用给了b，此时b也指向了猫类
b.show_info()
# __str__ 的使用
# __str__ 也是一种特殊的方法（魔法方法），当执行打印对象的语句时，它会被自动调用，
# 若类内没有对应的这个方法，输出的是对象引用地址，若有，则必须返回一个字符串
print(blue_cat)  # 打印对象，若类内没有 __str__，输出的是对象引用的地址，如：<__main__.Cat object at 0x0000027D8B7054F0>
print(red_cat)
# __del__ 的使用
# __del__ 也是一种特殊的方法（魔法方法），当执行删除对象的语句或因程序结束启动自动删除对象的功能时，它会被自动调用，


class Demo:
    def __init__(self, name1):
        print('我是 __init__ ，我被调用了。')
        self.name = name1

    def __del__(self):
        print(f'{self.name}无了，特此知会一声。')


demo1 = Demo('这是一个测试')  # 程序运行到最底端时宣告结束，此时所有记录将被销掉，这会触发 __del__ 的调用
demo2 = Demo('这还是一个测试')  # 由输出可见，代码顺序执行的同时，自动删除记录也是按生成时间的先后顺序执行的
del demo2  # 这就是删除对象的语句，执行后也会触发 __del__ 的调用
